package cc.rengu.redp.bizimpl.upmp.service.impl;

import cc.rengu.redp.bizimpl.upmp.domain.*;
import cc.rengu.redp.bizimpl.upmp.service.IUpmpSysParamService;
import cc.rengu.redp.bizimpl.upmp.vo.UpmpUserInfoVO;
import cc.rengu.redp.bizimpl.utils.Common;
import cc.rengu.redp.common.domain.QueryRequest;
import cc.rengu.redp.common.exception.RedpException;
import cc.rengu.redp.bizimpl.bean.FieldInfo;
import cc.rengu.redp.bizimpl.upmp.dao.BizHisMapper;
import cc.rengu.redp.bizimpl.upmp.domain.BizHis;
import cc.rengu.redp.bizimpl.enums.BizOprEnum;
import cc.rengu.redp.bizimpl.enums.PageOptFlagEnum;
import cc.rengu.redp.bizimpl.upmp.service.IBizHisService;
import cc.rengu.redp.bizimpl.utils.CommonUtils;
import cc.rengu.redp.bizimpl.utils.EnumUtils;
import cc.rengu.redp.common.utils.SortUtil;
import cc.rengu.redp.system.domain.User;
import com.alibaba.fastjson.JSON;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 临时表Service
 *
 * @author zhangxu
 */
@Service("bizHisService")
@DS("upmp")
@Transactional(rollbackFor = Exception.class, readOnly = true)
public class BizHisServiceImpl extends ServiceImpl<BizHisMapper, BizHis> implements IBizHisService {
    @Autowired
    private IUpmpSysParamService upmpSysParamService;
    /**
     * 保存临时表，需要重新开启事务，否则会保存到原事务开启的数据源中
     *
     * @param tmp
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void saveHis(BizHis tmp) {
        this.save(tmp);
    }

    /**
     * 删除后插入
     *
     * @param tmp BizHis
     */
    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public void deleteAndInsert(BizHis tmp) {
        this.baseMapper.deleteById(tmp.getRealId());
        saveHis(tmp);
    }

    /**
     * 获取临时表映射实体集
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public List<BizHis> getBizHisDetail(String id) {
        LambdaQueryWrapper<BizHis> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.select(BizHis::getRealId);
        lambdaQueryWrapper.orderByDesc(BizHis::getCreateTime);
        this.list(lambdaQueryWrapper);
        try {
            return this.list(lambdaQueryWrapper);
        } catch (Exception e) {
            log.error("查询历史记录异常", e);
            return null;
        }
    }
    @Override
    public IPage<BizHis> findByPage(QueryRequest request, BizHis info) {
        try {
            LambdaQueryWrapper<BizHis> queryWrapper = new LambdaQueryWrapper<>();
            if (Common.isNotBlank(info.getInstId())) {
                queryWrapper.likeRight(BizHis::getInstId, info.getInstId());
            }else {
                UpmpUserInfoVO user = CommonUtils.getCurrentUser(upmpSysParamService);
                queryWrapper.likeRight(BizHis::getInstId, user.getInstId());
            }
            if (Common.isNotBlank(info.getRealId())) {
                queryWrapper.likeRight(BizHis::getRealId, info.getRealId());
            }
            if (Common.isNotBlank(info.getMchntNo())) {
                queryWrapper.likeRight(BizHis::getMchntNo, info.getMchntNo());
            }
          if (Common.isNotBlank(info.getTermNo())) {
                queryWrapper.likeRight(BizHis::getTermNo, info.getTermNo());
            }
          if (Common.isNotBlank(info.getOprMenuId())) {
                queryWrapper.likeRight(BizHis::getOprMenuId, info.getOprMenuId());
            }
          if (Common.isNotBlank(info.getOprTableEname())) {
                queryWrapper.likeRight(BizHis::getOprTableEname, info.getOprTableEname());
            }
          if (Common.isNotBlank(info.getManageInstId())) {
                queryWrapper.likeRight(BizHis::getManageInstId, info.getManageInstId());
            }
            Page<BizHis> page = new Page<>();
            SortUtil.handlePageSort(request, page, true);
            return this.page(page, queryWrapper);
        } catch (Exception e) {
            log.error("查询失败", e);
            return null;
        }
    }

    /**
     * 新增历史记录
     *
     * @param entity      新记录
     * @param entityOld   原记录
     * @param user
     * @param bizOpr
     * @param updateTime
     * @param oprMenuId
     * @param oprMenuName
     * @param realId
     */
    @Override
    public void saveBizHisNew(Object entity, Object entityOld, UpmpUserInfoVO user, String instId, String bizOpr, String updateTime,
                              String oprMenuId, String oprMenuName, String realId, String mchntNo, String mchntName, String termNo) throws RedpException {
        if (ObjectUtils.isEmpty(entity)) {
            log.error("保存历史时参数 entity 不能为空");
            throw new RedpException("保存历史时参数 entity 不能为空");
        }
        if (ObjectUtils.isEmpty(entityOld)) {
            log.error("保存历史时参数 entityOld 不能为空");
            throw new RedpException("保存历史时参数 entityOld 不能为空");
        }
        if (ObjectUtils.isEmpty(realId)) {
            log.error("保存历史时参数 realId 不能为空");
            throw new RedpException("保存历史时参数 realId 不能为空");
        }

//                              String oprMenuId, String oprMenuName, String realId,String mchntNo,String mchntName,String termNo) {
        //历史表新增
        BizHis his = new BizHis();
        String bizData = "";
        if (BizOprEnum.OPR_DELETE.getType().equals(bizOpr)) {//物理删除时记录原记录的json
            bizData = JSON.toJSONString(entityOld);
        } else if (BizOprEnum.OPR_ADD.getType().equals(bizOpr)) {//新增时记录新记录的json
            bizData = JSON.toJSONString(entity);
        } else {
            bizData = getHisBizChangeData(entityOld, entity);
        }
        if (bizData.length() > 12000) {
            throw new RedpException("业务数据过长，请联系管理员！");
        }
        if (StringUtils.isEmpty(bizData)) {
            bizData = EnumUtils.getEnumDescriotionByValue(bizOpr, BizOprEnum.class, "getType", "getDesc").toString();
        }
        String ename = entity.getClass().getAnnotation(TableName.class).value().toLowerCase();
//        String cname = entity.getClass().getAnnotation(MetaData.class).value();
        //此处需改成记录变更的文本，如下：字段XXX从“123”变更为“456”,字段YYY从“abc”变更为“efg”
        String bizData1;
        String bizData2 = "";
        String bizData3 = "";
        if (bizData.length() > 4000) {
            bizData1 = bizData.substring(0, 3999);
            bizData2 = bizData.substring(4000);
        } else {
            bizData1 = bizData;
        }
        if (bizData2.length() > 4000) {
            bizData2 = bizData2.substring(0, 3999);
            bizData3 = bizData.substring(8000);
        }
        his.setBizChangeData1(bizData1);
        his.setBizChangeData2(bizData2);
        his.setBizChangeData2(bizData3);
        his.setBizOpr(bizOpr);
        his.setOprId(user.getId());
        his.setCreateTime(updateTime);
        his.setLastOprId(user.getId());
        his.setLastUpdateTime(updateTime);
        his.setMchntNo(mchntNo);
        his.setMchntName(mchntName);
        his.setTermNo(termNo);
        if (bizOpr.equals(convertOptFlagToBizOpr(PageOptFlagEnum.OPT_FLAG_PASS.getType()))
                || bizOpr.equals(convertOptFlagToBizOpr(PageOptFlagEnum.OPT_FLAG_REJECT.getType()))) {
            his.setLastAuditId(user.getId());
            his.setLastAuditTime(updateTime);
        }
        his.setOprMenuId(oprMenuId);
        his.setOprMenuName(oprMenuName);
//        his.setOprTableCname(cname);
        his.setOprTableEname(ename);
        his.setManageInstId(user.getOrgCode());
        his.setInstId(user.getInstId());
        his.setRealId(realId);
        this.saveHis(his);
    }

    /**
     * 组装bizhis表中bizChangeData
     *
     * @param oldObj
     * @param newObj
     * @return
     */
    public String getHisBizChangeData(Object oldObj, Object newObj) throws RedpException {
        StringBuffer bizChangeData = new StringBuffer();
        Field[] fields = newObj.getClass().getDeclaredFields();
        if (ObjectUtils.isEmpty(fields)) {
            for (Field field : fields) {
                FieldInfo newField = CommonUtils.getFieldValueByFieldName(field.getName(), newObj);
                FieldInfo oldField = CommonUtils.getFieldValueByFieldName(field.getName(), oldObj);
                if (!ObjectUtils.isEmpty(newField) && !ObjectUtils.isEmpty(oldField)) {
                    if (!newField.getValue().equals(oldField.getValue())) {
                        if (!StringUtils.isEmpty(bizChangeData)) {
                            bizChangeData.append(",");
                        }
//                        bizChangeData.append("字段" + newField.getFieldCname() + "[" + newField.getFieldName() + "]");
                        bizChangeData.append("字段[" + newField.getFieldName() + "]");
                        bizChangeData.append("[");
                        bizChangeData.append(newField.getFieldName());
                        bizChangeData.append("]从“");
                        bizChangeData.append(oldField.getValue());
                        bizChangeData.append("”改成“");
                        bizChangeData.append(newField.getValue());
                        bizChangeData.append("”");
                    }
                }
            }

        }
        return bizChangeData.toString();
    }

    /**
     * 将页面的optFlag转换成bizOpr
     *
     * @param pageOptFlag
     * @return
     */
    public String convertOptFlagToBizOpr(String pageOptFlag) {
        String bizOpr = "";
        PageOptFlagEnum[] optFlagEnums = PageOptFlagEnum.values();
        for (PageOptFlagEnum optFlagEnum : optFlagEnums) {
            if (pageOptFlag.equals(optFlagEnum.getType())) {
                bizOpr = optFlagEnum.getBizOpr();
                break;
            }
        }
        return bizOpr;
    }

    /**
     * 新增历史记录
     *
     * @param entitys     新记录
     * @param entityOlds  原记录
     * @param user
     * @param instId
     * @param bizOprs     每条记录的操作状态
     * @param updateTime
     * @param oprMenuId
     * @param oprMenuName
     * @param realIds     每条记录的realId
     */
    @Override
    public void saveBizHisList(List<?> entitys, List<?> entityOlds, UpmpUserInfoVO user, String instId, List<String> bizOprs, String updateTime,
                               String oprMenuId, String oprMenuName, List<String> realIds, String mchntNo, String mchntName, String termNo) throws RedpException {
        if (Common.isBlank(entitys) || entitys.size() == 0) {
            log.error("保存历史时参数 entitys 不能为空");
            throw new RedpException("保存历史时参数 entitys 不能为空");
        }
        if (Common.isBlank(entityOlds) || entityOlds.size() == 0) {
            log.error("保存历史时参数 entityOlds 不能为空");
            throw new RedpException("保存历史时参数 entityOlds 不能为空");
        }
        if (Common.isBlank(realIds) || realIds.size() == 0) {
            log.error("保存历史时参数 realIds 不能为空");
            throw new RedpException("保存历史时参数 realIds 不能为空");
        }
        if (entityOlds.size() != entitys.size()) {
            log.error("保存历史时新旧记录数不匹配");
            throw new RedpException("保存历史时新旧记录数不匹配");
        }
        if (entityOlds.size() != realIds.size()) {
            log.error("保存历史时传入的正式表id记录数与新记录数不匹配");
            throw new RedpException("保存历史时传入的正式表id记录数与新记录数不匹配");
        }
        if (entityOlds.size() != bizOprs.size()) {
            log.error("保存历史时传入的正式表状态记录数与新记录数不匹配");
            throw new RedpException("保存历史时传入的正式表状态记录数与新记录数不匹配");
        }

        for (int i = 0; i < entitys.size(); i++) {
            saveBizHisNew(entitys.get(i), entityOlds.get(i), user, instId, bizOprs.get(i), updateTime, oprMenuId, oprMenuName, realIds.get(i), mchntNo, mchntName, termNo);
        }
    }

    /**
     *  组装bizhis表中bizChangeData
     *
     * @param oldEntity
     * @param entity
     * @return
     */
    @Override
    public String getHisBizChangeData(BDeviceInfo oldEntity, BDeviceInfo entity) throws RedpException{
        StringBuffer bizChangeData = new StringBuffer();
        Field[] fields = entity.getClass().getDeclaredFields();
        if (Common.isNotBlank(fields)) {
            for (Field field : fields) {
                FieldInfo newField = CommonUtils.getFieldValueByFieldName(field.getName(), entity);
                FieldInfo oldField = CommonUtils.getFieldValueByFieldName(field.getName(), oldEntity);
                if (Common.isNotBlank(newField) && Common.isNotBlank(oldField)) {
                    if (!newField.getValue().equals(oldField.getValue())) {
                        if (Common.isNotBlank(bizChangeData)) {
                            bizChangeData.append(",");
                        }
                        bizChangeData.append("字段" + newField.getFieldCname() + "[" + newField.getFieldName() + "]");
                        bizChangeData.append("[");
                        bizChangeData.append(newField.getFieldName());
                        bizChangeData.append("]从“");
                        bizChangeData.append(oldField.getValue());
                        bizChangeData.append("”改成“");
                        bizChangeData.append(newField.getValue());
                        bizChangeData.append("”");
                    }
                }
            }

        }
        return bizChangeData.toString();
    }

}
